package com.app.framework.utils;

import com.app.domain.vo.user.UserVo;
import com.app.exception.BusinessException;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import io.micrometer.common.util.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Date;
import java.util.Objects;

/**
 * Token工具类
 */
public class TokenUtils {

    /**
     * 自定义加密盐
     */
    private static final String jwtToken = "qq547241650#$@!@";

    /**
     * 从Header中获取token
     */
    public static String getToken() {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        return request.getHeader("token");
    }

    /**
     * 添加token
     *
     * @param userId 用户ID
     */
    public static String saveToken(Long userId) {
        Algorithm algorithm = Algorithm.HMAC256(jwtToken);
        return JWT.create()
                .withJWTId(userId.toString())
                .withClaim("id", userId)
                //一天的有效时间(过期时间)
                .withExpiresAt(new Date(System.currentTimeMillis() + 24L * 60 * 60 * 1000))
                //颁发时间
                .withIssuedAt(new Date())
                .sign(algorithm);
    }

    /**
     * 检查token
     *
     * @param token token
     */
    public static UserVo checksToken(String token) {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        if (!validateToken(token)) {
            throw new BusinessException("token错误");
        }
        Object object = RedisUtils.get("token:" + token);
        Assert.notNull(object, "用户未登录,或登录已失效!");
        return (UserVo) object;
    }

    /**
     * token校验
     *
     * @param token token
     * @return 布尔值
     */
    public static boolean validateToken(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(jwtToken);
            JWTVerifier verifier = JWT.require(algorithm).build();
            verifier.verify(token);
            return true;
        } catch (JWTVerificationException exception) {
            return false;
        }
    }

    /**
     * 获取登录用户信息
     */
    public static UserVo getLoginUser() {
        UserVo loginUser = checksToken(getToken());
        Assert.notNull(loginUser, "用户未登录,或登录已失效!");
        return loginUser;
    }

    /**
     * 获取登录用户ID
     */
    public static Long getLoginUserId() {
        UserVo loginUser = checksToken(getToken());
        Assert.notNull(loginUser, "用户未登录,或登录已失效!");
        return loginUser.getId();
    }

    /**
     * 获取当前请求的用户ID
     */
    public static Long getRequestUserId() {
        UserVo loginUser = checksToken(getToken());
        return loginUser == null ? null : loginUser.getId();
    }

    /**
     * 获取当前请求的用户信息
     */
    public static UserVo getRequestUser() {
        return checksToken(getToken());
    }

}